fix: print "Listening on" only after the socket is bound (#4400)#4413
Merged
Conversation
Emit the "Listening on ..." startup message after startServer()/ startPipeServer() returns rather than before, so the announced URL is guaranteed to be accepting connections. httpuv binds synchronously, so by the time the handle is returned the port is live. Previously the message could be printed one statement before the bind, leaving a window (widened under load) where anything scraping the line as a readiness signal (shinytest2, log watchers) could reach a not-yet-bound port.
schloerke
marked this pull request as ready for review
July 15, 2026 18:26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4400
Summary
The
Listening on http://…startup message was emitted one statement before thestartServer()call that binds the listening socket. Because httpuv binds synchronously, moving the message to afterstartServer()/startPipeServer()returns guarantees the announced URL is already accepting connections. The domain-socket branch also validates themaskattribute before binding so an invalid socket errors without printing a misleading line. This matters because theListening online is used as a readiness signal (shinytest2, process supervisors, log watchers); under load the freshly-forked process could be descheduled between the two statements, leaving a window where the advertised port refused connections.Verification
Unit tests in
tests/testthat/test-server.Rmock the synchronous bind and assert the message is emitted only after it returns (and not at all underquiet = TRUE). Reverting the reorder makes the ordering test fail; restoring it passes. Manual reproduction using the issue reporter's tracer now shows the port accepting connections by the time the line prints.